import { MerchantDailyIncome } from '@app/db/entities/MerchantDailyIncome';
import { Body, Controller, Get, ParseIntPipe, Post, Query, Req } from '@nestjs/common';
import { IncomeLogPageDto } from './dto/incomeLog'
import { And, FindOptionsWhere, In, LessThanOrEqual, MoreThanOrEqual } from 'typeorm';
import { BaseController } from '../base/base.controller';
import { DbService } from '@app/db';
import { MerchantService } from './merchant.service';
import { DtoPipe } from '../pipes/dto/dto.pipe';
import { UpdatePayeeDto, WithdrawalPageDto } from './dto/withdrawal';
import { WithdrawalRecord } from '@app/db/entities/WithdrawalRecord';

@Controller('merchant')
export class MerchantController extends BaseController{
    constructor(
        private readonly db:DbService,
        private readonly service:MerchantService
    ){
        super()
    }

    @Get('statistics')
    async statistics(@Req() { member }) {
        const data = await this.service.statistics(member.tenantId)
        return this.successRes(data)
    }

    @Post('daily/rang/amount/chargeCount')
    async incomeChart(@Body() dates:{startDate:number, endDate:number}, @Req() { member }) {
        let where:FindOptionsWhere<MerchantDailyIncome> = {
            merchantId : member.tenantId
        }

        if(dates.startDate == dates.endDate) {
            where.date = dates.startDate
        }else {
            where.date = And(MoreThanOrEqual(dates.startDate), LessThanOrEqual(dates.endDate))
        }

        const rows = await this.db.merchantDailyIncome.find(where, ['amount', 'chargeOrderCount', 'date'])


        return this.successRes(rows)
    }

    @Get('account')
    async account(@Req() { member }) {
        const account = await this.db.merchant.findOne({id : member.tenantId})
        return this.successRes(account)
    }

    @Post('update/payee')
    async updatePayee(@Body(new DtoPipe({skipMissingProperties : true})) dto:UpdatePayeeDto, @Req() { member }){
        const r = await this.db.merchant.update({id : member.tenantId}, dto)
        return r > 0 ? this.successRes() : this.failRes()
    }


    @Post('income/log/page')
    async incomeLogPage(@Query() dto:IncomeLogPageDto, @Req() { member }) {
        let result:PaginationResult<MerchantDailyIncome> = {
            total : 0,
            rows : []
        }

        let where:FindOptionsWhere<MerchantDailyIncome> = {
            merchantId : member.tenantId
        }

        if(dto.startTime || dto.endTime) {
            if(dto.startTime == dto.endTime) {
                where.date = dto.startTime
            }else {
                const dates:any = []
                if(dto.startTime) {
                    dates.push(MoreThanOrEqual(dto.startTime))
                }

                if(dto.endTime) {
                    dates.push(LessThanOrEqual(dto.endTime))
                }

                where.date = And(...dates)
            }
        }

        

        result.total = await this.db.merchantDailyIncome.count(where)

        if(result.total > 0) {
            result.rows = await this.db.merchantDailyIncome.pagination(dto.pageNo, dto.pageSize, where, null, {id : 'DESC'})
        }
        

        return this.successRes(result)

    }

    //申请提现
    @Post('apply/withdrawal')
    async applyWithdrawal(@Body('amount') amount:number, @Req() {member, memberId}) {
        amount = Number(amount)
        if(isNaN(amount) || amount <= 0) {
            return this.failRes()
        }

        const r = await this.service.applyWithdrawal(amount, memberId, member.tenantId)
        if(r == -1) return this.failRes('可提现金额不足')
        if(r == null) return this.failRes()
        return this.successRes()
    }

    //撤回提现
    @Post('revoke/withdrawal')
    async revokeWithdrawal(@Body('id', ParseIntPipe) id:number, @Req() {member, memberId}) {
        const r = await this.service.revokeWithdrawal(id)
        if(r == true) return this.successRes()
        return this.failRes('撤销失败')
    }

    //提现记录
    @Post('withdrawal/record')
    async withdrawalRecord(@Body() dto:WithdrawalPageDto, @Req() {member, memberId}) {
        let result:PaginationResult<WithdrawalRecord & {member?:string}> = {
            total : 0,
            rows : []
        }

        let where:FindOptionsWhere<WithdrawalRecord> = {
            
        }

        if(dto.startTime || dto.endTime) {
            if(dto.startTime == dto.endTime) {
                where.createTime = dto.startTime
            }else {
                if(dto.startTime) {
                    where.createTime = MoreThanOrEqual(dto.startTime)
                }

                if(dto.endTime) {
                    where.createTime = LessThanOrEqual(dto.endTime)
                }
            }
        }

        if(dto.status !== undefined) {
            where.status = dto.status
        }

        result.total = await this.db.withdrawalRecord.count(where)

        if(result.total > 0) {
            result.rows = await this.db.withdrawalRecord.pagination(dto.pageNo, dto.pageSize, where, null, {id : 'DESC'})
            const memberIds:number[] = []
            result.rows.forEach(row => {
                if(!memberIds.includes(row.memberId)) {
                    memberIds.push(row.memberId)
                }
            })

            const members = await this.db.member.find({id : memberIds.length == 1 ? memberIds[0] : In(memberIds)}, ['name', 'id'])
            result.rows.forEach(row => {
                const i = members.findIndex(m => m.id == row.memberId)
                if(i >= 0) {
                    row.member = members[i].name
                }
                
            })

        }

        return this.successRes(result)
    }
}
